

import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:suburban_inside_flutter/pages/load_history_page.dart';
import 'package:suburban_inside_flutter/pages/save_history_page.dart';
import 'package:suburban_inside_flutter/widget/colorful_button.dart';
import 'package:suburban_inside_flutter/widget/page_wrapper.dart';

import 'viewmodel/general_viewmodel.dart';

class Screen extends StatefulWidget {
  const Screen({super.key});

  @override
  State<Screen> createState() => _ScreenState();
}

class _ScreenState extends State<Screen> {

  double borderRadius = 16;

  final ValueNotifier<Offset> _mousePosition = ValueNotifier(const Offset(0, 0));  // 鼠标位置
  Offset _mousePositionNormalized = const Offset(0, 0);
  final double _mousePositionDefaultDiff = 8;
  double _mousePositionDiffX = 0;
  double _mousePositionDiffY = 0;
  final ValueNotifier<bool> _showBox = ValueNotifier(false);  // 控制 Box 的显示
  final GlobalKey _mouseRegionKey = GlobalKey();
  final GlobalKey _cursorPopupBoxKey = GlobalKey();

  Size? getSizeByKey (GlobalKey key) {
    final RenderBox renderBox;
    try {
      renderBox = key.currentContext?.findRenderObject() as RenderBox;
      return renderBox.size;
    } catch(e) {
      return null;
    }

  }

  static const double _maxObsSize = 360;
  static const double lrPadding = 10;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: const Color.fromARGB(255, 237, 237, 237),
        borderRadius: BorderRadius.circular(borderRadius),
      ),
      child: Stack(
        children: [
          Center(
            child: Padding(
              padding: const EdgeInsets.fromLTRB(lrPadding, 0, lrPadding, 0),
              child: Column(
                mainAxisSize: MainAxisSize.max,
                children: [
                  const Expanded(child: SizedBox.shrink()),
                  MouseRegion(
                    cursor: SystemMouseCursors.precise,
                    onEnter: (event) {
                      // setState(() {});
                      _showBox.value = true;
                    },
                    onExit: (event) {
                      // setState(() {});
                      _showBox.value = false;
                    },
                    onHover: (event) {
                      // setState(() {});
                      var myPopupBoxSize = getSizeByKey(_cursorPopupBoxKey);
                      var myMouseRegionSize = getSizeByKey(_mouseRegionKey);
                      _mousePosition.value = event.localPosition;  // 获取鼠标相对于本地区域的坐标
            
                      var size = _mouseRegionKey.currentContext!.size;
                      _mousePositionNormalized = _mousePosition.value / size!.height;
            
                      _mousePositionDiffX = _mousePositionDiffY = _mousePositionDefaultDiff;
            
                      if (myPopupBoxSize == null) {
                        return;
                      }
            
                      if (_mousePosition.value.dx + myPopupBoxSize.width > myMouseRegionSize!.width - _mousePositionDefaultDiff) {
                        _mousePositionDiffX = - _mousePositionDefaultDiff - myPopupBoxSize.width;
                      }
            
                      if (_mousePosition.value.dy + myPopupBoxSize.height > myMouseRegionSize.height - _mousePositionDefaultDiff) {
                        _mousePositionDiffY = - _mousePositionDefaultDiff - myPopupBoxSize.height;
                      }
                    },
                    child: GestureDetector(
                      onTap: () {
                        print("obs tapped");
                        print("  x: ${_mousePositionNormalized.dx}");
                        print("  y: ${_mousePositionNormalized.dy}");
                        GeneralViewModel().selectActionState.select(
                          _mousePositionNormalized, GeneralViewModel().selectActionState.radius_raw
                        );
                      },
                      child: ConstrainedBox(
                        constraints: const BoxConstraints(
                          maxHeight: _maxObsSize
                        ),
                        child: AspectRatio(
                          aspectRatio: 1,
                          child: Container(
                              key: _mouseRegionKey,
                              // constraints: const BoxConstraints(
                              //   minHeight: double.infinity, // 设置高度填满父容器
                              // ),
                              decoration: BoxDecoration(
                                border: Border.all(
                                  width: 1.2,
                                  color: Colors.black,
                                  strokeAlign: BorderSide.strokeAlignOutside
                                )
                              ),
            
                              child: Stack(
                                children: [
                                  Positioned.fill(
                                    child: ObsImageView(
                                      mouseRegionKey: _mouseRegionKey,
                                    ),
                                  ),
            
                                  ListenableBuilder(
                                    listenable: _mousePosition,
                                    builder: (context, _) {
                                      return ListenableBuilder(
                                        listenable: _showBox,
                                        builder: (context, _) {
                                          if (_showBox.value) {
                                            return AnimatedPositioned(
                                              left: _mousePosition.value.dx + _mousePositionDiffX,  // Box 位于鼠标的右下方
                                              top: _mousePosition.value.dy + _mousePositionDiffY,
                                              duration: const Duration(milliseconds: 50),
                                              child: Container(
                                                key: _cursorPopupBoxKey,
                                                padding: const EdgeInsets.all(8),
                                                decoration: BoxDecoration(
                                                  color: Colors.black.withOpacity(0.7),
                                                  borderRadius: BorderRadius.circular(8),
                                                ),
                                                child: Text(
                                                  'x: ${_mousePositionNormalized.dx.toStringAsFixed(3)}, y: ${_mousePositionNormalized.dy.toStringAsFixed(3)}',
                                                  style: TextStyle(color: Colors.white),
                                                ),
                                              ),
                                            );
                                          }
                                          return const SizedBox.shrink();
                                        }
                                      );
                                    }
                                  )
            
                                ],
                              )
                          ),
                        ),
                      ),
                    ),
                  ),
            
                  const SizedBox(height: 10,),
                  SizedBox(
                    height: 20,
                    child: ConstrainedBox(
                      constraints: const BoxConstraints(maxWidth: _maxObsSize),
                      child: ListenableBuilder(
                        listenable: GeneralViewModel().obsImageViewmodel,
                        builder: (context, _) {
                          return FutureBuilder(
                            future: GeneralViewModel().obsImageViewmodel.updateTotalState(),
                            builder: (context, snapshot) {
                              if (snapshot.connectionState==ConnectionState.waiting) {
                                return const Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Expanded(child: SizedBox.shrink()),
                                    Text("Total Reward: --"),
                                    Expanded(child: SizedBox.shrink()),
                                    Text("Total Cost: --"),
                                    Expanded(child: SizedBox.shrink()),
                                  ],
                                );
                              }
                              else if (snapshot.hasError) {
                                return const SizedBox.shrink();
                              }
                              else {
                                return Row(
                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                  children: [
                                    Text("Step: ${snapshot.data!.$1}"),
                                    Text("Total Reward: ${snapshot.data!.$2}"),
                                    Text("Total Cost: ${snapshot.data!.$3}"),
                                  ],
                                );
                              }
                            },
                          );
                        },
                      ),
                    ),
                  ),
                  const Expanded(child: SizedBox.shrink()),
                ],
              ),
            ),
          ),

          TooltipTheme(
            data: const TooltipThemeData(
              waitDuration: Duration(milliseconds: 300),
              preferBelow: false),
            child: Positioned(
              right: 10,
              bottom: 10,
              // child: Container(width: 100, height: 100, color: Colors.blue),
              child: Column(
                children: [
                  IconButton(
                    icon: const Icon(Icons.refresh, size: 23,),
                    onPressed: () => GeneralViewModel().obsImageViewmodel.notify(),
                    tooltip: "refresh",
                  ),
                  IconButton(
                    icon: const Icon(Icons.undo, size: 18),
                    onPressed: () {
                      GeneralViewModel().selectActionState.restoreLastAction(
                        undoImplementation: () => GeneralViewModel().pushRequest("undo")
                      );
                    },
                    tooltip: "undo",
                  ),
                  IconButton(
                    icon: const Icon(Icons.redo, size: 18),
                    onPressed: () => GeneralViewModel().pushRequest("redo").then((_) {
                      GeneralViewModel().selectActionState.cancel();
                    }),
                    tooltip: "redo",
                  ),
                  ListenableBuilder(
                    listenable: GeneralViewModel().hotMemoryState,
                    builder: (context, _) {
                      final temp = GeneralViewModel().hotMemoryState;
                      return IconButton(
                        icon: Icon(
                          Icons.memory_sharp,
                          size: 22,
                          color: temp.enable ? Colors.lightBlue : null
                        ),
                        onPressed: () => temp.tap(),
                        tooltip: "hot memory",
                      );
                    }
                  ),
                  IconButton(
                    icon: const Icon(Icons.rotate_left_outlined, color: Colors.redAccent,),
                    onPressed: () => GeneralViewModel().pushRequest("reset").then((_) {
                      GeneralViewModel().selectActionState.cancel();
                    }),
                    tooltip: "reset",
                  ),
                ],
              ),
            ),
          ),

          TooltipTheme(
            data: const TooltipThemeData(
                waitDuration: Duration(milliseconds: 300),
                preferBelow: false),
            child: Positioned(
              left: 10,
              bottom: 10,
              // child: Container(width: 100, height: 100, color: Colors.blue),
              child: Column(
                children: [
                  IconButton(
                    icon: const Icon(Icons.save_sharp,size: 19,),
                    tooltip: "save actions",
                    onPressed: () {
                      print("save pressed");
                      showDialog(
                        context: context,
                        builder: (context) {
                          return const SaveHistoryPage();
                        },
                      );
                    },
                  ),
                  IconButton(
                    icon: const Icon(Icons.history, size: 22),
                    onPressed: () {
                      print("load pressed");
                      showDialog(
                        context: context,
                        builder: (context) {
                          return const LoadHistoryPage();
                        },
                      );
                    },
                    tooltip: "load actions",
                  ),
                ],
              ),
            ),
          ),


          Positioned(
            bottom: 16,
            left: 0,
            right: 0,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ColorfulButton(
                  bgColor: Colors.black45,
                  bgColorHover: Colors.black87,
                  height: 24,
                  paddingLR: 12,
                  onTap: () {
                    print("random button tapped");
                    GeneralViewModel().pushRequest("random");
                  },
                  child: const Text("random"),
                ),
                const SizedBox(width: 8),
                ColorfulButton(
                  bgColor: Colors.black45,
                  bgColorHover: Colors.blue,
                  height: 24,
                  paddingLR: 12,
                  onTap: () {
                    print("predict button tapped");
                  },
                  child: const Text("predict"),
                ),
                const SizedBox(width: 4),
                ColorfulButton(
                  // fgColor: Colors.black54,
                  // fgColorHover: Colors.blue,
                  bgColor: Colors.black26,
                  bgColorHover: Colors.blue,
                  height: 24,
                  paddingLR: 4,
                  child: const Icon(Icons.more_horiz, size: 20),
                  onTap: () {
                    print("predict settings tapped");
                  },
                ),
              ],
            ),
          ),

        ],
      ),
    );
  }
}


class ObsImageView extends StatefulWidget {
  const ObsImageView({super.key, required this.mouseRegionKey});

  final GlobalKey mouseRegionKey;

  @override
  State<ObsImageView> createState() => _ObsImageViewState();
}

class _ObsImageViewState extends State<ObsImageView> {
  Size getSize() {
    return widget.mouseRegionKey.currentContext!.size!;
  }

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      size = getSize();
    });
    super.initState();
  }

  Size size = const Size(0, 0);

  final previewColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned.fill(
          child: ListenableBuilder(
            listenable: GeneralViewModel().obsImageViewmodel,
            child: Image.file(
              File("map.png"),
              fit: BoxFit.cover,
            ),
            builder: (context, child) {
              return FutureBuilder(
                  future: GeneralViewModel().obsImageViewmodel.updateImage(),
                  builder: (context, snapshot) {
                    if (snapshot.connectionState==ConnectionState.waiting) {
                      if (GeneralViewModel().obsImageViewmodel.oldImage != null) {
                        return Image.memory(GeneralViewModel().obsImageViewmodel.oldImage!, fit: BoxFit.cover,);
                      }
                      return const CircularProgressIndicator();
                    }
                    else if (snapshot.hasError) {
                      return Center(
                        child: ColorfulButton(
                          style: const TextStyle(height: 2),
                          fgColor: Colors.white,
                          bgColor: Colors.black54,
                          fgColorHover: Colors.white,
                          bgColorHover: Colors.blue,
                          onTap: () {
                            print("re-fetch obs image");
                            GeneralViewModel().obsImageViewmodel.notify();
                          },
                          child: const Text("re-fetch"),
                        ),
                      );
                    }
                    else {
                      return Image.memory(snapshot.data!, fit: BoxFit.cover,);
                    }
                  }
              );
            },
          ),
        ),


        ListenableBuilder(
          listenable: GeneralViewModel().selectActionState,
          builder: (context, _) {
            if (GeneralViewModel().selectActionState.selecting) {
              var temp = GeneralViewModel().selectActionState;
              return Positioned(
                left: size.width * (temp.offset.dx - temp.radius),
                top: size.height * (temp.offset.dy - temp.radius),
                child: Container(
                  width: size.width * temp.radius*2,
                  height: size.width * temp.radius*2,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: previewColor, // 设置边框颜色
                      width: 1.6, // 设置边框宽度
                    ),
                  ),
                )
              );
            }
            return const SizedBox.shrink();
          }
        ),

        ListenableBuilder(
            listenable: GeneralViewModel().selectActionState,
            builder: (context, _) {
              if (GeneralViewModel().selectActionState.selecting) {
                var temp = GeneralViewModel().selectActionState;
                const double iconSize = 20;
                return Positioned(
                    left: size.width * (temp.offset.dx) - iconSize / 2,
                    top: size.height * (temp.offset.dy) - iconSize / 2,
                    child: Icon(Icons.add, color: previewColor, size: iconSize,)
                );
              }
              return const SizedBox.shrink();
            }
        ),

      ],
    );
  }
}
